/*
 * ComponentInitializer.java
 *
 * Created on September 6, 2006, 3:24 PM
 *
 * (C) 2006 R. Alexander Milowski
 */

package com.smallx.xproc.library;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.infoset.component.Component;
import org.infoset.component.ComponentContextBase;
import org.infoset.xml.Document;
import org.infoset.xml.Name;
import org.infoset.xml.NamespaceScope;
import org.infoset.xml.XMLException;

/**
 *
 * @author alex
 */
public class ComponentInitializer {
   
   Name name;
   Component component;
   List<DestinationAdapter> adapters;
   Map<Name,Object> staticInputs;
   Map<Name,Object> staticParameters;
   Component.Context parentContext;
   NamespaceScope scope;
   
   /** Creates a new instance of ComponentInitializer */
   public ComponentInitializer(Name name,Component component) {
      this.name = name;
      this.component = component;
      this.parentContext = null;
      this.staticInputs = null;
      this.staticParameters = null;
      this.adapters = null;
      this.scope = null;
   }
   
   public Name getName() {
      return name;
   }
   
   public Component getComponent() {
      return component;
   }
   
   public void setNamespaceScope(NamespaceScope scope) {
      this.scope = scope;
   }
   
   public void setParentContext(Component.Context context)
   {
      this.parentContext = context;
   }
   
   public void addStaticParameter(Name name, Object value)
   {
      if (staticParameters==null) {
         staticParameters = new HashMap<Name,Object>();
      }
      staticParameters.put(name,value);
   }
   
   public void addParameters(Map<Name,? extends Object> parameters)
   {
      if (staticParameters==null) {
         staticParameters = new HashMap<Name,Object>();
      }
      staticParameters.putAll(parameters);
   }
   
   public void addDestinationAdapter(DestinationAdapter adapter) {
      if (adapters==null) {
         adapters = new ArrayList<DestinationAdapter>();
      }
      adapters.add(adapter);
   }
   public void rebindOutput(DestinationAdapter adapter) 
      throws XMLException
   {
      adapter.reset();
      component.bindOutputPort(adapter.getOutputPort(),adapter);
   }
   
   public void addStaticInput(Name port,Object input) {
      if (staticInputs==null) {
         staticInputs = new HashMap<Name,Object>();
      }
      staticInputs.put(port,input);
   }
   
   public void init() 
      throws XMLException
   {
      ComponentContextBase context = new ComponentContextBase(parentContext,null,scope);
      if (staticParameters!=null) {
         for (Name name : staticParameters.keySet()) {
            context.setParameter(name,staticParameters.get(name));
         }
      }
      component.init(context);
   }
   public void bindStatics() 
      throws XMLException
   {
      if (staticInputs!=null) {
         for (Name inputPort : staticInputs.keySet()) {
            Object value = staticInputs.get(inputPort);
            if (value instanceof URI) {
               component.bindResource(inputPort,(URI)value);
            } else {
               component.bindResource(inputPort,(Document)value);
            }
         }
      }
      
   }
   
   public void bindOutputs() 
      throws XMLException
   {
      if (adapters!=null) {
         for (DestinationAdapter adapter : adapters) {
            adapter.reset();
            component.bindOutputPort(adapter.getOutputPort(),adapter);
         }
      }
   }
   
   public void onStart() 
      throws XMLException
   {
      component.onStart();
   }
   
   public void onEnd() 
      throws XMLException
   {
      component.onEnd();
   }
}
